<?php
/*
 * @Description    : WebSocketApiController
 * @Author         : QianLong
 * @Date           : 2023-05-04 10:39:14
 * @LastEditors    : QianLong
 * @Site           : http://www.21ds.cn
 * @LastEditTime   : 2024-01-16 16:59:54
 */

declare(strict_types=1);

namespace App\Controller;

use App\Common\RedisCache;
use App\Constants\Status;
use App\Exception\ApiException;
use App\Job\SignFailAddJob;
use Qianlong\Validate\Validate;

class WebSocketApiController extends AbstractController
{
  public function server_push()
  {
    $valitor = new Validate();
    $valitor->addColumn('ws_id')->required();
    $valitor->addColumn('room')->optional();
    $valitor->addColumn('message')->required();
    if ($valitor && !$this->validate($valitor)) {
      throw new ApiException(Status::CODE_BAD_REQUEST, $valitor->getError()->__toString());
    }
    unset($valitor);
    $param = $this->request->all();
    $redisCache = new RedisCache;
    $serverInfo = $redisCache->getWsServer($param['ws_id']);
    $remoteIp = $this->dataResource->getClientIp($this->request);
    $newSign2 = (new \App\Service\Common)->generateSignature($param, $serverInfo['server_secret']);
    if ($param['sign'] != $newSign2['sign']) {
      $logData['url'] = $this->request->fullUrl();
      $logData['remoteIp'] = $remoteIp;
      $logData['user_sign'] = $param['sign'];
      $logData['server_sign'] = $newSign2['sign'];
      $logData['server_query'] = $newSign2['query'];
      $logData['uid'] = $serverInfo['uid'];
      queue_push(new SignFailAddJob($logData));
      return $this->response->json(Status::CODE_FAIL, 'sign签名校验失败');
    }
    if ($serverInfo['status'] != 1) {
      return $this->response->json(Status::CODE_FAIL, '当前配置状态不可用，如需使用，请登录柠聚开发平台启用后重试', []);
    }
    $io = \Hyperf\Context\ApplicationContext::getContainer()->get(\Hyperf\SocketIOServer\SocketIO::class);
    $room = '';
    if (isset($param['room']) && !empty($param['room'])) {
      $room = $serverInfo['uid'] . '_' . $param['room'];
    } else {
      $param['room'] = '';
    }
    $toUser = '';
    if (isset($param['union_id']) && !empty($param['union_id'])) {
      $toUser = $redisCache->getSetSocketUnionId($serverInfo['uid'] . '_' . $param['union_id']);
    }
    $event_name = (isset($param['event_name']) && !empty($param['event_name'])) ? $param['event_name'] : 'say';
    // 向房间内其他用户推送（不含当前用户）
    $sayData['room'] = $param['room'];
    $sayData['message'] = $param['message'];
    if (!empty($toUser)) {
      $sayData['to_user'] = $toUser;
      $io->to($toUser)->emit($event_name, json_encode($sayData, JSON_UNESCAPED_UNICODE));
    }else if(!empty($room)){
      $sayData['to_user'] = $param['room'];
      $io->to($room)->emit($event_name, json_encode($sayData, JSON_UNESCAPED_UNICODE));
    }
    return $this->response->json(Status::CODE_OK, '推送成功', $sayData);
  }
}
